package com.hcx.poi.hssf.eventmodel;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.CellRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.RKRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.hssf.record.SSTRecord;

import com.hcx.excel.xlsx.Cell;
import com.hcx.excel.xlsx.Row;
import com.hcx.poi.eventmodel.SheetRowHandler;

public class HSSFHandler implements HSSFListener {
	private String sheetName = "";
	private SSTRecord sstrec;
	private SheetRowHandler rowHandler;
	private SheetParsingStatus parsingStatus = SheetParsingStatus.NotStart;
	private Row currRow;
	private int columnCount = 0;
	private List<String> sheetNames = new ArrayList<String>();
	private int currSheetIndex = -1;
	private CellRecordHandler cellRecordHandler = null;

	public HSSFHandler(String sheetName) {
		this.sheetName = sheetName;
	}

	@Override
	public void processRecord(Record record) {
		if (record instanceof CellRecord) {
			handleCellRecord((CellRecord) record);
		} else if (SSTRecord.sid == record.getSid()) {
			cellRecordHandler = new CellRecordHandler((SSTRecord) record);
			sstrec = (SSTRecord) record;
		} else if (BoundSheetRecord.sid == record.getSid()) {
			handleBoundSheetRecord((BoundSheetRecord) record);
		} else if (RowRecord.sid == record.getSid()) {
			RowRecord r = (RowRecord) record;
			columnCount = columnCount < r.getLastCol() ? r.getLastCol()
					: columnCount;
		} else if (BOFRecord.sid == record.getSid()) {
			handleBOFRecord((BOFRecord) record);
		}
	}

	public void setSheetRowHandler(SheetRowHandler handler) {
		rowHandler = handler;
	}

	/**
	 * 处理数据单元格
	 * 
	 * @param cellRecord
	 */
	private void handleCellRecord(CellRecord cellRecord) {
		if (!isParsing()) {
			return;
		}
		handleCell(cellRecordHandler.handle(cellRecord), cellRecord.getRow(),
				cellRecord.getColumn());
	}

	private void handleBOFRecord(BOFRecord record) {
		if (record.getType() == BOFRecord.TYPE_WORKSHEET) {
			currSheetIndex++;

			if (sheetNames.get(currSheetIndex).equals(sheetName)
					&& SheetParsingStatus.NotStart.equals(parsingStatus)) {
				parsingStatus = SheetParsingStatus.Parsing;
			}

			if (SheetParsingStatus.Parsing.equals(parsingStatus)
					&& (!sheetNames.get(currSheetIndex).equals(sheetName))) {
				if (currRow != null) {
					handleRow(currRow);
				}
				parsingStatus = SheetParsingStatus.ParseEnd;
			}
		}
	}

	private void handleBoundSheetRecord(BoundSheetRecord record) {
		sheetNames.add(record.getSheetname());
	}

	private void handleCell(Cell cell, int rowNum, int colNum) {
		if (currRow == null) {
			if (rowNum != 0) {
				for (int i = 0; i < rowNum; i++) {
					handleRow(new Row(i, columnCount));
				}
			}
			currRow = new Row(rowNum, columnCount);
			currRow.addCell(cell, colNum);
		} else {
			if (rowNum == currRow.getRowNum()) {
				currRow.addCell(cell, colNum);
			} else {
				handleRow(currRow);
				// 当前情况下 currRow 中的 rowNum 肯定小于 rowNum
				for (int i = currRow.getRowNum() + 1; i < rowNum; i++) {
					handleRow(new Row(i, columnCount));
				}
				currRow = new Row(rowNum, columnCount);
				currRow.addCell(cell, colNum);
			}
		}
	}

	private boolean isParsing() {
		return SheetParsingStatus.Parsing.equals(parsingStatus) ? true : false;
	}

	private void handleRow(Row row) {
		if (null != rowHandler) {
			rowHandler.handleRow(row);
		}
	}

	private static enum SheetParsingStatus {
		NotStart, Parsing, ParseEnd
	}
}
